#include "wms_wifi.h"
#include "wms_http.h" // 添加HTTP模块头文件

// 初始化静态变量
bool WifiManagerClass::shouldSaveConfig = false;

// 创建全局实例
WifiManagerClass WifiManager;

// 初始化WiFi管理器
bool WifiManagerClass::init() {
    // 初始化LittleFS文件系统
    if (!LittleFS.begin(true)) {
        Serial.println("LittleFS挂载失败！");
        return false;
    }
    
    Serial.println("LittleFS挂载成功");
    
    // 从文件系统加载配置
    loadConfigFromFS();
    
    // 设置WiFiManager的回调函数
    wifiManager.setSaveConfigCallback(saveConfigCallback);
    
    // 设置AP模式的超时时间
    wifiManager.setConfigPortalTimeout(PORTAL_TIMEOUT / 1000);  // 转换为秒
    
    // 设置AP模式的名称和密码
    wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 4, 1), IPAddress(192, 168, 4, 1), IPAddress(255, 255, 255, 0));
    
    // 设置默认服务器URL
    if (strlen(serverUrl) == 0) {
        strcpy(serverUrl, DEFAULT_SERVER_URL);
    }
    
    return true;
}

// 连接到WiFi
bool WifiManagerClass::connect() {
    // 创建自定义参数
    // 参数: id, placeholder, default value, length
    serverUrlParam = new WiFiManagerParameter("server_url", "服务器URL", serverUrl, 100);
    
    // 添加参数到WiFiManager
    wifiManager.addParameter(serverUrlParam);
    
    // 尝试连接WiFi，如果失败则启动配置门户
    if (!wifiManager.autoConnect(AP_NAME, AP_PASSWORD)) {
        Serial.println("连接失败，重启ESP32...");
        delay(3000);
        ESP.restart();
        return false;
    }
    
    Serial.println("WiFi连接成功");
    Serial.print("IP地址: ");
    Serial.println(WiFi.localIP());
    
    // 更新全局WiFi状态
    set_wifi_status(WIFI_STATUS_CONNECTED);
    
    // 如果需要保存配置，则保存到文件系统
    if (shouldSaveConfig) {
        // 获取自定义参数值
        strncpy(serverUrl, serverUrlParam->getValue(), sizeof(serverUrl));
        Serial.print("获取到的服务器URL: ");
        Serial.println(serverUrl);
        
        saveConfigToFS();
        shouldSaveConfig = false;
    }
    
    // 释放参数内存
    delete serverUrlParam;
    
    return true;
}

// 重置WiFi设置
void WifiManagerClass::resetSettings() {
    // 删除配置文件
    if (LittleFS.exists(WIFI_CONFIG_FILE)) {
        LittleFS.remove(WIFI_CONFIG_FILE);
        Serial.println("WiFi配置文件已删除");
    }
    
    // 重置WiFiManager
    wifiManager.resetSettings();
    Serial.println("WiFi设置已重置");
    
    // 重置服务器URL
    strcpy(serverUrl, DEFAULT_SERVER_URL);
    
    // 重启ESP32
    delay(1000);
    ESP.restart();
}

// 检查是否已连接WiFi
bool WifiManagerClass::isConnected() {
    return WiFi.status() == WL_CONNECTED;
}

// 获取IP地址
String WifiManagerClass::getIPAddress() {
    if (isConnected()) {
        return WiFi.localIP().toString();
    }
    return "未连接";
}

// 启动配置门户
void WifiManagerClass::startConfigPortal() {
    // 创建自定义参数
    serverUrlParam = new WiFiManagerParameter("server_url", "服务器URL", serverUrl, 100);
    
    // 添加参数到WiFiManager
    wifiManager.addParameter(serverUrlParam);
    
    // 启动配置门户
    if (!wifiManager.startConfigPortal(AP_NAME, AP_PASSWORD)) {
        Serial.println("无法启动配置门户，重启ESP32...");
        delay(3000);
        ESP.restart();
    }
    
    Serial.println("配置门户已关闭");
    
    // 如果需要保存配置，则保存到文件系统
    if (shouldSaveConfig) {
        // 获取自定义参数值
        strncpy(serverUrl, serverUrlParam->getValue(), sizeof(serverUrl));
        Serial.print("获取到的服务器URL: ");
        Serial.println(serverUrl);
        
        saveConfigToFS();
        shouldSaveConfig = false;
    }
    
    // 释放参数内存
    delete serverUrlParam;
}

// 处理WiFi事件
void WifiManagerClass::handleEvents() {
    // 检查WiFi连接状态
    if (WiFi.status() != WL_CONNECTED) {
        static unsigned long lastReconnectAttempt = 0;
        unsigned long currentMillis = millis();
        
        // 每5秒尝试重新连接一次
        if (currentMillis - lastReconnectAttempt > 5000) {
            lastReconnectAttempt = currentMillis;
            Serial.println("WiFi连接断开，尝试重新连接...");
            // 更新全局WiFi状态为断开连接
            set_wifi_status(WIFI_STATUS_DISCONNECTED);
            WiFi.reconnect();
        }
    } else {
        // 如果WiFi已连接，但全局状态不是已连接，则更新状态
        device_state_t *pdevice = get_device_state();
        if (pdevice->wifi_state != WIFI_STATUS_CONNECTED) {
            Serial.println("WiFi已重新连接，更新全局状态");
            set_wifi_status(WIFI_STATUS_CONNECTED);
        }
    }
}

// 设置服务器URL
void WifiManagerClass::setServerUrl(const char* url) {
    strcpy(serverUrl, url);
    // 保存配置
    saveConfigToFS();
}

// 获取服务器URL
const char* WifiManagerClass::getServerUrl() {
    return serverUrl;
}

// 绑定到服务器
bool WifiManagerClass::bindToServer() {
    if (!isConnected()) {
        Serial.println("WiFi未连接，无法绑定到服务器");
        return false;
    }
    
    if (strlen(serverUrl) == 0) {
        Serial.println("服务器URL为空，无法绑定");
        return false;
    }
    
    Serial.print("尝试绑定到服务器: ");
    Serial.println(serverUrl);
    
    // 调用HTTP模块的设备绑定函数
    // 获取设备ID (从HTTP模块获取)
    const char* deviceId = get_http_device_id();
    
    // 调用绑定函数
    bool result = handle_device_binding(serverUrl, deviceId);
    
    if (result) {
        Serial.println("绑定服务器成功");
        
        // 更新全局设备状态
        device_state_t *pdevice = get_device_state();
        
        // 设置设备绑定状态
        set_device_bind_status(DEVICE_BINDED);
        
        // 设置服务器URL
        set_server_url(serverUrl);
        
        // 设置设备ID
        set_device_id(deviceId);
        
        // 设置WiFi状态
        set_wifi_status(WIFI_STATUS_CONNECTED);
        
        // 打印当前设备状态
        Serial.print("全局设备状态 - 绑定状态: ");
        Serial.println(pdevice->device_bind_state == DEVICE_BINDED ? "已绑定" : "未绑定");
        Serial.print("全局设备状态 - 服务器URL: ");
        Serial.println(pdevice->server_url);
        Serial.print("全局设备状态 - 设备ID: ");
        Serial.println(pdevice->device_id);
        Serial.print("全局设备状态 - WiFi状态: ");
        Serial.println(pdevice->wifi_state == WIFI_STATUS_CONNECTED ? "已连接" : "未连接");
    } else {
        Serial.println("绑定服务器失败");
    }
    
    return result;
}

// 保存WiFi配置到文件系统
bool WifiManagerClass::saveConfigToFS() {
    Serial.println("保存WiFi配置到文件系统");
    
    // 创建JSON文档
    JsonDocument doc;
    
    // 保存WiFi凭据
    doc["ssid"] = WiFi.SSID();
    doc["password"] = WiFi.psk();
    
    // 保存服务器URL
    doc["server_url"] = serverUrl;
    
    // 打开文件进行写入
    File configFile = LittleFS.open(WIFI_CONFIG_FILE, "w");
    if (!configFile) {
        Serial.println("无法打开配置文件进行写入");
        return false;
    }
    
    // 将JSON序列化到文件
    if (serializeJson(doc, configFile) == 0) {
        Serial.println("写入配置文件失败");
        configFile.close();
        return false;
    }
    
    configFile.close();
    Serial.println("WiFi配置已保存");
    return true;
}

// 从文件系统加载WiFi配置
bool WifiManagerClass::loadConfigFromFS() {
    // 检查配置文件是否存在
    if (!LittleFS.exists(WIFI_CONFIG_FILE)) {
        Serial.println("配置文件不存在，使用默认设置");
        return false;
    }
    
    // 打开配置文件
    File configFile = LittleFS.open(WIFI_CONFIG_FILE, "r");
    if (!configFile) {
        Serial.println("无法打开配置文件");
        return false;
    }
    
    // 获取文件大小
    size_t size = configFile.size();
    if (size > 1024) {
        Serial.println("配置文件过大");
        configFile.close();
        return false;
    }
    
    // 解析JSON
    JsonDocument doc;
    DeserializationError error = deserializeJson(doc, configFile);
    configFile.close();
    
    if (error) {
        Serial.print("解析配置文件失败: ");
        Serial.println(error.c_str());
        return false;
    }
    
    // 提取WiFi凭据
    const char* ssid = doc["ssid"];
    const char* password = doc["password"];
    
    // 提取服务器URL
    if (doc.containsKey("server_url")) {
        const char* url = doc["server_url"];
        if (url && strlen(url) > 0) {
            strcpy(serverUrl, url);
            Serial.print("从配置文件加载的服务器URL: ");
            Serial.println(serverUrl);
        }
    }
    
    if (ssid && password) {
        // 预设WiFi凭据
        wifiManager.setSTAStaticIPConfig(IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0));
        
        Serial.println("从配置文件加载的WiFi凭据:");
        Serial.print("SSID: ");
        Serial.println(ssid);
        Serial.println("密码: ********");
        
        return true;
    }
    
    return false;
}

// 配置保存回调
void WifiManagerClass::saveConfigCallback() {
    Serial.println("需要保存配置");
    shouldSaveConfig = true;
} 